package com.fw.system.admin.service.impl;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.NumberUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.fw.common.Builder;
import com.fw.common.IdXD;
import com.fw.constant.Constant;
import com.fw.enums.UserAccountEnum;
import com.fw.mes.Result;
import com.fw.system.admin.domain.*;
import com.fw.system.admin.domain.vo.UljoinVo;
import com.fw.system.admin.domain.vo.UserAgentVo;
import com.fw.system.admin.domain.vo.UserLevelVo;
import com.fw.system.admin.domain.vo.UserVo;
import com.fw.system.admin.mapper.*;
import com.fw.system.admin.service.IFwAgentRegionService;
import com.fw.system.admin.service.IFwRuleDatasService;
import com.fw.utils.DateUtils;
import com.fw.utils.StringUtils;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import com.fw.system.admin.service.IFwUserService;
import org.springframework.transaction.annotation.Transactional;

import static com.fw.enums.ShopStatus.PASS_SUCCESS;

/**
 * 用户Service业务层处理
 *
 * @author yanwei
 * @date 2021-05-10
 */
@Service
public class FwUserServiceImpl extends ServiceImpl<FwUserMapper, FwUser> implements IFwUserService
{
    @Autowired
    private FwUserMapper fwUserMapper;

    @Autowired
    private FwLockStorageMapper lockStorageMapper;

    @Autowired
    private FwMoneysMapper moneysMapper;

    @Autowired
    private FwUljoinMapper uljoinMapper;

    @Autowired
    private FwIdentityMapper identityMapper;

    @Autowired
    private FwShopMapper shopMapper;

    @Autowired
    private IFwRuleDatasService ruleDatasService;

    @Autowired
    private IFwAgentRegionService agentRegionService;

    @Autowired
    private IdXD idXD;

    /**
     * 查询用户
     *
     * @param id 用户ID
     * @return 用户
     */
    @Override
    public FwUser selectFwUserById(String id)
    {
        return fwUserMapper.selectFwUserById(id);
    }

    /**
     * 查询用户列表
     *
     * @param fwUser 用户
     * @return 用户
     */
    @Override
    public List<UserVo> selectFwUserList(FwUser fwUser)
    {
        Page<FwUser> fwUsers = (Page<FwUser>) fwUserMapper.selectFwUserList(fwUser);
        // 增加额外逻辑
        // 1.用户所有的身份
        List<UserVo> userVoList = fwUsers.parallelStream().map(item -> {
            UserVo userVo = new UserVo();
            BeanUtil.copyProperties(item, userVo);
            userVo.setUljoinVos(builderUlVos(userVo.getId()));
            return userVo;
        }).collect(Collectors.toList());
        Page<UserVo> fwUsersPage = new Page<UserVo>();
        BeanUtil.copyProperties(fwUsers,fwUsersPage,"elementData");
        fwUsersPage.addAll(userVoList);
        return fwUsersPage;


    }

    private List<UljoinVo> builderUlVos(String userId) {
        List<UljoinVo> uljoinVoList = Lists.newArrayList();
        List<FwUljoin> fwUljoins = uljoinMapper.selectList(Wrappers.<FwUljoin>lambdaQuery().eq(FwUljoin::getUserId, userId));
        // 需用普通 for 不可嵌套并姓流
        for (FwUljoin fwUljoin : fwUljoins) {
            UljoinVo uljoinVo = new UljoinVo();
            BeanUtil.copyProperties(fwUljoin,uljoinVo);
            uljoinVo.setIdentityName(identityMapper.selectById(fwUljoin.getIdentityId()).getIdentityName());
            uljoinVoList.add(uljoinVo);
        }

        return uljoinVoList;
    }

    /**
     * 新增用户
     *
     * @param fwUser 用户
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insertFwUser(FwUser fwUser)
    {
        flagUserParmes(fwUser);

        //初始化用户
        FwUser user = new FwUser();
        BeanUtil.copyProperties(fwUser,user);
        user.setId(idXD.nextId())//用户编号
                .setSystemHost(idXD.nextId());//用户编号(对甲方)


        //更新用户积分兑换比例
        //获取积分兑换比例
        if (Objects.nonNull(user.getToRelease())){
            FwRuleDatas datas = ruleDatasService.getOne(Wrappers.<FwRuleDatas>lambdaQuery().eq(FwRuleDatas::getId, Constant.IsRuleData.INTEGRAL_RELEASE));
            user.setToRelease(datas.getRuleCount());
        }

        /** 初始化钱包 */
        FwMoneys moneys = new FwMoneys()
                .setId(idXD.nextId())
                .setUserId(user.getId())
                .setIntegral(new BigDecimal(0))
                .setDisappear(new BigDecimal(0))
                .setShangJia(new BigDecimal(0)).setManShangjia(NumberUtil.add(0D)).setTecShangjia(NumberUtil.add(0D));
        moneys.setCreateTime(DateUtils.getNowDate());
        moneysMapper.insert(moneys);


        user.setCreateTime(DateUtils.getNowDate());
        //送回token
        return fwUserMapper.insert(user);
    }

    private void flagUserParmes(FwUser fwUser) {
        FwUser one = getOne(Wrappers.<FwUser>lambdaQuery().eq(FwUser::getPhone, fwUser.getPhone()));
        Assert.isTrue(Objects.isNull(one) || one.getId().equals(fwUser.getId()),"该用户已经注册!");

        //验证用户使用的邀请码是否正确
        if (StringUtils.isNotBlank(fwUser.getParentId())) {
            //获取其上级数据
            FwUser parentUser =getOne(Wrappers.<FwUser>lambdaQuery().eq(FwUser::getId, fwUser.getParentId()));
            Assert.isTrue(Objects.nonNull(parentUser),"没有该上级,请核实!");
        }
        // 校验用户 是否 管理？ 技术？
        Integer isAccount = fwUser.getIsAccount();

        if (!UserAccountEnum.USER.getCode().equals(isAccount)) {
            Assert.isTrue(Objects.isNull( getOne(Wrappers.<FwUser>lambdaQuery().ne(StringUtils.isNotBlank(fwUser.getId()),FwUser::getId,fwUser.getId()).eq(FwUser::getIsAccount,isAccount))),"系统默认已经有对应的管理,或技术帐号了,请核实!");
        }
    }

    /**
     * 修改用户
     *
     * @param fwUser 用户
     * @return 结果
     */
    @Override
    public int updateFwUser(FwUser fwUser)
    {
        flagUserParmes(fwUser);
        fwUser.setUpdateTime(DateUtils.getNowDate());
        if (!fwUser.getUiJoinIds().isEmpty())
            uljoinMapper.delete(Wrappers.<FwUljoin>lambdaQuery().eq(FwUljoin::getUserId,fwUser.getId()).notIn(FwUljoin::getId,fwUser.getUiJoinIds()));
        return fwUserMapper.updateFwUser(fwUser);
    }

    /**
     * 批量删除用户
     *
     * @param ids 需要删除的用户ID
     * @return 结果
     */
    @Override
    public int deleteFwUserByIds(String[] ids)
    {
        return fwUserMapper.deleteFwUserByIds(ids);
    }

    /**
     * 删除用户信息
     *
     * @param id 用户ID
     * @return 结果
     */
    @Override
    public int deleteFwUserById(String id)
    {
        return fwUserMapper.deleteFwUserById(id);
    }



    @Override
    public List<UserLevelVo> userLevel(String parentId) {
        // 把自己的统计一遍哦
        LinkedList<UserLevelVo> userLevelVoList = Lists.newLinkedList();
        List<FwUser> fwUserList = list(Wrappers.<FwUser>lambdaQuery().eq(FwUser::getParentId, parentId));
        for (FwUser fwUser : fwUserList) {
            userLevelVoList.addLast(builderUserLevelVo(fwUser.getId()));
        }
        userLevelVoList.addFirst(builderUserLevelVo(parentId));
        return userLevelVoList;
    }


    @Override
    public UserAgentVo getUserAgentVo(String userId) {
        UserAgentVo userAgentVo = new UserAgentVo();
        FwUser fwUser = getById(userId);
        BeanUtil.copyProperties(fwUser,userAgentVo);
        userAgentVo.setUljoinVos(builderUlVos(userId));
        // 补充钱包信息
        UserLevelVo userLevelVo = builderUserLevelVo(userId);
        BeanUtil.copyProperties(userLevelVo,userAgentVo);
        return userAgentVo;
    }

    /**
     * 统计自己的数据
     * @param userId
     * @return
     */
    private UserLevelVo builderUserLevelVo(String userId){
        UserLevelVo userLevelVo = Builder.of(UserLevelVo::new).build();
        FwUser fwUser = getById(userId);
        BeanUtil.copyProperties(fwUser,userLevelVo);
        // 统计直推人数
        userLevelVo.setPushCount(count(Wrappers.<FwUser>lambdaQuery().eq(FwUser::getParentId,userId)));
        // 是否商户
        userLevelVo.setIsShop(shopMapper.selectList(Wrappers.<FwShop>lambdaQuery().eq(FwShop::getUserId,userId).eq(FwShop::getStatus,PASS_SUCCESS.getCode())).isEmpty() ?2 :1  );
        // 用户等级
        FwUljoin fwUljoin = uljoinMapper.selectOne(Wrappers.<FwUljoin>lambdaQuery().eq(FwUljoin::getUserId, userId).eq(FwUljoin::getIsUse, Constant.IsUsr.IS_USR));
        userLevelVo.setLevelName("暂无等级");
        if (Objects.nonNull(fwUljoin)) {
            userLevelVo.setLevelName(Optional.ofNullable(identityMapper.selectFwIdentityById(fwUljoin.getIdentityId()).getIdentityName()).orElse("暂无等级"));
        }
        //锁仓数量
        Long lockNumber = lockStorageMapper.selectList(Wrappers.<FwLockStorage>lambdaQuery().eq(FwLockStorage::getUserId, userId).eq(FwLockStorage::getFlag, Constant.LockStorage.LOCK_ING)).parallelStream().map(item -> item.getLockCount()).reduce(Long::sum).orElse(0L);
        userLevelVo.setLockShangjia(lockNumber);
        // 钱包数据
        FwMoneys moneys = moneysMapper.selectOne(Wrappers.<FwMoneys>lambdaQuery().eq(FwMoneys::getUserId, userId));
        userLevelVo.setDisappear(moneys.getDisappear());
        userLevelVo.setIntegral(moneys.getIntegral());
        userLevelVo.setShangJia(moneys.getShangJia());
        userLevelVo.setShangJia(moneys.getShangJia().add(Optional.ofNullable(moneys.getManShangjia()).orElse(NumberUtil.add(0D)).add(Optional.ofNullable(moneys.getTecShangjia()).orElse(NumberUtil.add(0D)))));
        return userLevelVo;

    }


}
